

try:
    from typing import Literal, TypedDict, Tuple, Union, List
    ROLES = Literal['ground-control', 'locomotive-control']
    PLATFORM_TYPES = Literal['ESP32S3', 'ESP32']
    # 双向自保持电磁铁的状态表示
    BIDIR_SLFHLD_EM_STATES = Literal['A', "B"]
    # 道岔种类
    TURNOUT_TYPES = Literal[
        'left_hand_turnout',  # 左开道岔
        "right_hand_turnout",  # 右开道岔
        'bilateral_turnout',  # 对称道岔
        'three_row_turnout'  # 三开道岔
    ]
    # 不同道岔的状态
    LEFT_HAND_TURNOUT_STATES = Literal[
        'normal', 'left'
    ]
    RIGHT_HAND_TURNOUT_STATES = Literal[
        'normal', 'right'
    ]
    BILATERAL_HAND_TURNOUT_STATES = Literal[
        'left', 'right'
    ]
    THREE_ROW_TURNOUT_STATES = Literal[
        'normal', 'left', 'right'
    ]

    # Pin Assignments
    class MotorPinAssignment(TypedDict):
        sw1: int  # 开关1
        sw2: int  # 开关2
        pwm: int  # PWM

    class ElectroMagneticPinAssignment(TypedDict):
        sw1: int
        sw2: int
        # pwm: int
        x595: "X595PinAssignment"

    class X595PinAssignment(TypedDict):
        x595_clear: int  # 74XX595的清零引脚，0为清零，1不清零
        x595_latch: int  # 74XX595的锁存引脚
        x595_data: int  # 74XX595的数据引脚
        x595_clock: int  # 74XX595的时钟引脚

    # Requests and Responses
    class ElectroMagnetRequest(TypedDict):
        # 电磁铁控制指令
        index: int
        state: BIDIR_SLFHLD_EM_STATES

    class FileInfoResponse(TypedDict):
        name: str
        size: int

    class RMFileRequest(TypedDict):
        name: str
        type: Literal["directory", "file"]

    class InitializationData(TypedDict):
        # Data to initialize the locomotive
        control_station_ip: str

    # 设备配置，在控制端和设备中均会存储。
    class DeviceFunctionalConfig(TypedDict):
        uuid: str  # 配置项的UUID，通过对比UUID，从而对比配置是否是最新的。
        role: ROLES # 设备的角色
        activated: bool # 该配置是否生效。同名配置最多生效一个。
        device_name: str  # 与wifi_device的名称一致。
        alias: str # 设备别名，更加方便记忆，在控制器网页上如此显示。

        # 以下配置为车载控制器使用的内容
        motor_reversed: bool  # 电机是否反向
        drive_curve: List[int]  # 牵引曲线，地面站端配置9个点

        # 以下配置为地面控制器使用的内容
        # 注意：电磁铁的反向信息不在控制器上存储，而是在控制电脑的道岔配置项中存储
        electromagnet_595_chips: int  # 控制电磁铁的74xx595芯片的数量
        led_595_chips: int  # 控制LED的74xx595芯片的数量

    class WifiConfig(TypedDict):
        ssid: str
        password: str

    class SystemBasicConfig(TypedDict):
        ssid: str  # SSID to connect in STA mode
        password: str  # Password to connect in STA mode to the SSID above
        role: ROLES
        name: str  # The name of locomotive or ground machines controller

    class ResourceInfo(TypedDict):
        # All space info are in kB
        mem_used: float
        mem_total: float
        flash_used: float
        flash_total: float

    # Messages
    class ConnectedMsg(TypedDict):
        type: Literal['ETT_JOIN']
        name: str
        ip: str
        mask: str
        role: ROLES

    class UpHeartbeatMsg(TypedDict):
        """
        ESP32发送给控制站的心跳包
        """
        type: Literal['ETT_HEARTBEAT_UP']
        name: str  # ESP32设备的名称

    class DownHeartbeatMsg(TypedDict):
        """
        控制站发送给ESP32的心跳包
        """
        type: Literal['ETT_HEARTBEAT_DOWN']

    AUDIO_ACTIONS = Literal['play', 'stop']

    class AudioControl(TypedDict):
        kind: Literal['audio']
        cmd: AUDIO_ACTIONS

    class ControlMsg(TypedDict):
        """
        控制站发送给ESP32的控制指令
        """
        type: Literal['ETT_DEVICE_CONTROL']
        payload: AudioControl

    UDP_UP_MSG_TYPES = Union[UpHeartbeatMsg, ConnectedMsg]

except:
    pass
